﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Security.Principal;
using Newtonsoft.Json;
using SG.Productivity.DesktopControlPanel.Support;
using SocketIOClient;
using SocketIOClient.Messages;

namespace SG.Productivity.DesktopControlPanel.ParallelQuery
{
    public partial class SocketIoClientComponent : Component
    {
        public SocketIoClientComponent()
        {
            InitializeComponent();
        }

        public SocketIoClientComponent(IContainer container)
        {
            container.Add(this);

            InitializeComponent();
        }

        private Client _client;
        private LineRegistration _lineRegistration;
        public void Connect(Uri uri)
        {
            _client = new Client(uri.ToString());
            _client.Opened += SocketOpened;
            _client.Message += SocketMessage;
            _client.SocketConnectionClosed += SocketConnectionClosed;
            _client.Error += SocketError;

            _client.On("connect", Connect);

            _client.Connect();
        }

        class LineRegistration
        {
            public LineRegistration(WindowsIdentity identity, UserInfo info)
            {
                Line = info.TelephoneNumber;
                User = identity.Name;
            }

            [JsonProperty("line")]
            public string Line { get; private set; }

            [JsonProperty("user")]
            public string User { get; private set; }
        }

        private void Connect(IMessage message)
        {
            Debug.Print("socket opened: {0} message: {1}", _client.IsConnected, message);

            if (!_client.IsConnected)
                return;

            WindowsIdentity user;
            UserInfo info;
            if (UserInfo.TryGetCurrentUser(out user, out info))
            {
                _lineRegistration = new LineRegistration(user, info);
                _client.Emit("client_register", _lineRegistration);
            }
        }

        private void SocketOpened(object sender, EventArgs e)
        {
            Debug.Print("socket opened: {0}", _client.IsConnected);
        }

        private void SocketMessage(object sender, MessageEventArgs e)
        {
            Debug.Print("socket message: {0}", e.Message.MessageText);
        }

        private void SocketConnectionClosed(object sender, EventArgs e)
        {
            Debug.Print("socket closed: {0}", _client.IsConnected);
        }

        private void SocketError(object sender, ErrorEventArgs e)
        {
            Debug.Print("socket error: {0}\n{1}\n", e.Message, e.Exception);
        }

        public void Disconnect()
        {
            if (_client == null || !_client.IsConnected)
                return;

            if (_lineRegistration != null)
                _client.Emit("client_unregister", _lineRegistration);

            _client.Close();
            _client = null;
            _lineRegistration = null;
        }
    }
}
